/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.escom.healthlc.controller;

import com.escom.healthlc.business.MedicoBusiness;
import com.escom.healthlc.business.RegistrarBusiness;
import com.escom.healthlc.entidad.MedicoVO;
import com.escom.healthlc.entidad.PacienteVO;
import com.escom.healthlc.entidad.PersonaVO;
import com.escom.healthlc.entidad.UsuarioVO;
import com.escom.healthlc.utils.Constantes;
import com.escom.healthlc.utils.LazySorterMngMedico;
import com.escom.healthlc.utils.LazySorterPaciente;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Carlos
 */
@ManagedBean(name = "MngMedicosController")
@ViewScoped
public class MngMedicosController {

    private Logger logger = LoggerFactory.getLogger(MngMedicosController.class);

    private MedicoVO createMedico;
    private MedicoVO selectMedico;
    private List<MedicoVO> retrieveMedico;
    private LazyDataModel<MedicoVO> medicoLazyModel;
    private boolean renderPanelAlta;
    private boolean renderPanelConsulta;
    private boolean validarUsuario;

    @ManagedProperty("#{MedicoBusiness}")
    private MedicoBusiness medicoBusiness;
    @ManagedProperty("#{RegistrarBusiness}")
    private RegistrarBusiness registrarBusiness;

    @PostConstruct
    private void initMngMedicosController() {
        executeLimpiarObjects(null);
    }

    public void executeCrearMedico(ActionEvent acEvt) {
        logger.debug("executeCrearPaciente");
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        medicoBusiness.crearMedico(createMedico);
        int estado = medicoBusiness.getEstado();
        String messageEstado = medicoBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }
        executeLimpiarObjects(acEvt);

    }

    public void executeConsultarMedico(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        retrieveMedico = medicoBusiness.consultarMedicos();
        crearLazyModelPaciente();
        int estado = medicoBusiness.getEstado();
        String messageEstado = medicoBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }
        executeChangeToRetrieve();

    }

    public void executeActualizarMedico(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
//        medicoBusiness.actualizarMedico(selectMedico);
        int estado = medicoBusiness.getEstado();
        String messageEstado = medicoBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }
        executeLimpiarObjects(acEvt);

    }

    public void executeEliminarMedico(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        medicoBusiness.eliminarMedico(selectMedico);
        int estado = medicoBusiness.getEstado();
        String messageEstado = medicoBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }
        executeLimpiarObjects(acEvt);

    }

    public void executeChangeToCreate() {
        renderPanelAlta = true;
        renderPanelConsulta = false;
    }

    public void executeChangeToRetrieve() {
        renderPanelAlta = false;
        renderPanelConsulta = true;
    }

    public void executeValidarUsuario() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        validarUsuario = registrarBusiness.validarUsuario(createMedico);
        if (validarUsuario) {
            UsuarioVO usuario = createMedico.getUsuario();
            usuario.setNick("");
        }
    }

    public void executeLimpiarObjects(ActionEvent acEvt) {
        createMedico = new MedicoVO();
        createMedico.setUsuario(new UsuarioVO());
        selectMedico = new MedicoVO();
        selectMedico.setUsuario(new UsuarioVO());
        retrieveMedico = new ArrayList<MedicoVO>();
        renderPanelAlta = false;
        renderPanelConsulta = false;
    }

    private void crearLazyModelPaciente() {
        medicoLazyModel = new LazyDataModel<MedicoVO>() {
            List<MedicoVO> datasource = retrieveMedico;

            @Override
            public MedicoVO getRowData(String rowKey) {
                for (MedicoVO medico : datasource) {
                    if (medico.getIdMedico().equals(rowKey)) {
                        return medico;
                    }
                }
                return null;
            }

            @Override
            public List<MedicoVO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
                List<MedicoVO> data = new ArrayList<MedicoVO>();

                //filter  
                for (MedicoVO medico : datasource) {
                    logger.debug("Medico {}", medico.toString());
                    boolean match = true;
                    for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                        try {
                            String filterProperty = it.next();
                            Field field;
                            String filterValue = "";
                            String fieldValue;

                            if (filterProperty.contains("nombre") || filterProperty.contains("apPaterno")) {
                                filterValue = filters.get(filterProperty);
                                PersonaVO persona = medico;
                                field = persona.getClass().getDeclaredField(filterProperty);
                                field.setAccessible(true);
                                fieldValue = String.valueOf(field.get(persona));
                            } else {
                                filterValue = filters.get(filterProperty);
                                field = medico.getClass().getDeclaredField(filterProperty);
                                field.setAccessible(true);
                                fieldValue = String.valueOf(field.get(medico));
                            }

                            if (filterValue == null || fieldValue.contains(filterValue)) {
                                match = true;
                            } else {
                                match = false;
                                break;
                            }
                        } catch (Exception e) {
                            match = false;
                        }
                    }

                    if (match) {
                        data.add(medico);
                    }
                }

//                sort  
                if (sortField != null) {
                    Collections.sort(data, new LazySorterMngMedico(sortField, sortOrder));
                }
                if (sortField == null) {
                    sortField = "defaultSortField";
                }
                //rowCount  
                int dataSize = data.size();
                this.setRowCount(dataSize);

                //paginate  
                if (dataSize > pageSize) {
                    try {
                        return data.subList(first, first + pageSize);
                    } catch (IndexOutOfBoundsException e) {
                        return data.subList(first, first + (dataSize % pageSize));
                    }
                } else {
                    return data;
                }
            }

            @Override
            public Object getRowKey(MedicoVO t) {
                return t.getIdMedico();
            }
        };
    }

    public void setMedicoBusiness(MedicoBusiness medicoBusiness) {
        this.medicoBusiness = medicoBusiness;
    }

    public void setRegistrarBusiness(RegistrarBusiness registrarBusiness) {
        this.registrarBusiness = registrarBusiness;
    }

    public MedicoVO getCreateMedico() {
        return createMedico;
    }

    public void setCreateMedico(MedicoVO createMedico) {
        this.createMedico = createMedico;
    }

    public MedicoVO getSelectMedico() {
        return selectMedico;
    }

    public void setSelectMedico(MedicoVO selectMedico) {
        this.selectMedico = selectMedico;
    }

    public LazyDataModel<MedicoVO> getMedicoLazyModel() {
        return medicoLazyModel;
    }

    public void setMedicoLazyModel(LazyDataModel<MedicoVO> medicoLazyModel) {
        this.medicoLazyModel = medicoLazyModel;
    }

    public boolean isRenderPanelAlta() {
        return renderPanelAlta;
    }

    public void setRenderPanelAlta(boolean renderPanelAlta) {
        this.renderPanelAlta = renderPanelAlta;
    }

    public boolean isRenderPanelConsulta() {
        return renderPanelConsulta;
    }

    public void setRenderPanelConsulta(boolean renderPanelConsulta) {
        this.renderPanelConsulta = renderPanelConsulta;
    }

    public boolean isValidarUsuario() {
        return validarUsuario;
    }

    public void setValidarUsuario(boolean validarUsuario) {
        this.validarUsuario = validarUsuario;
    }

}
